package br.com.revolution.command;

import java.io.File;
import java.io.IOException;

import org.farng.mp3.MP3File;
import org.farng.mp3.TagException;
import org.farng.mp3.id3.AbstractID3v2;
import org.farng.mp3.id3.ID3v1;

import br.com.revolution.dto.ReturnExecutionDTO;
import br.com.revolution.dto.RevolutionDTO;
import br.com.revolution.properties.RevolutionPropertiesEnum;
import br.com.revolution.util.FileUtils;
import br.com.revolution.util.StringUtils;

public class Mp3TagEditorRevolutionCommand implements RevolutionCommand {
	
	public ReturnExecutionDTO execute(RevolutionDTO dto) {
		ReturnExecutionDTO returnExecution = null;
		
		try {
			if (dto.getFile().isDirectory()) {
				returnExecution = processDirectory(dto);
			} else {
				returnExecution = processFile(dto);
			}
		} catch (TagException e) {
			returnExecution = new ReturnExecutionDTO();
			returnExecution.setMessage(RevolutionPropertiesEnum.MESSAGE_ERROR_TAG_EXCEPTION.getValue());
			returnExecution.setSucess(false);
		} catch (IOException e) {
			returnExecution = new ReturnExecutionDTO();
			returnExecution.setMessage(RevolutionPropertiesEnum.MESSAGE_ERROR_IO_EXCEPTION.getValue());
			returnExecution.setSucess(false);
		}
		
		return returnExecution;
	}

	private ReturnExecutionDTO processFile(RevolutionDTO dto) throws IOException, TagException {
		MP3File mp3file = new MP3File(dto.getFile());
		AbstractID3v2 id3v2 = mp3file.getID3v2Tag();
		editID3v2Tags(id3v2, dto);
		mp3file.save();
		
		return createReturnOk();
	}

	private ReturnExecutionDTO processDirectory(RevolutionDTO dto) throws IOException, TagException {
		MP3File mp3file = null;
		AbstractID3v2 id3v2 = null;
		ID3v1 id3v1 = null;
		
		String songTitle = null;
		int trackNumberOnAlbum = 0;
		
		File[] listFiles = dto.getFile().listFiles();
		
		for (File file : listFiles) {
			if (file.getName().toLowerCase().endsWith(StringUtils.MP3_EXTENSION)) {
				
				songTitle = getSongTitle(file.getName());
				trackNumberOnAlbum++;
				
				dto.setSongTitle(songTitle);
				dto.setTrackNumberOnAlbum(Integer.toString(trackNumberOnAlbum));
				
				mp3file = new MP3File(file);
				id3v2 = mp3file.getID3v2Tag();
				id3v1 = mp3file.getID3v1Tag();
				editID3v2Tags(id3v2, dto);
				editID3v1Tags(id3v1, dto);
				mp3file.save();
				
				FileUtils.rename(file, StringUtils.createMp3FileName(
						dto.getTrackNumberOnAlbum(),
						dto.getLeadArtist(),
						dto.getSongTitle()));
			}
		}
		
		return createReturnOk();
	}
 
	private String getSongTitle(String fullName) {
		String[] names = fullName.split("-");
		String fullTitle = names[names.length - 1];
		String title = fullTitle.substring(0, fullTitle.length() - 4);
		
		return StringUtils.capitalize(title);
	}

	private ReturnExecutionDTO createReturnOk() {
		ReturnExecutionDTO returnExecution = new ReturnExecutionDTO();
		returnExecution.setMessage(RevolutionPropertiesEnum.MESSAGE_EXECUTION_OK.getValue());
		returnExecution.setSucess(true);
		return returnExecution;
	}

	private void editID3v1Tags(ID3v1 id3v1, RevolutionDTO dto) {
		id3v1.setAlbum(dto.getAlbumTitle());
		id3v1.setAlbumTitle(dto.getAlbumTitle());
		id3v1.setArtist(dto.getLeadArtist());
		id3v1.setComment(dto.getSongComment());
		id3v1.setLeadArtist(dto.getLeadArtist());
		id3v1.setSongComment(dto.getSongComment());
		//id3v1.setSongGenre(dto.getSongGenre());
		//id3v1.setSongLyric(dto.getSongLyric());
		id3v1.setSongTitle(dto.getSongTitle());
		id3v1.setTitle(dto.getSongTitle());
		id3v1.setTrackNumberOnAlbum(dto.getTrackNumberOnAlbum());
		id3v1.setYear(dto.getYearReleased());
		id3v1.setYearReleased(dto.getYearReleased());
	}
	
	
	private void editID3v2Tags(AbstractID3v2 id3v2, RevolutionDTO dto) {
		id3v2.setAlbumTitle(dto.getAlbumTitle());
		id3v2.setAuthorComposer(dto.getAuthorComposer());
		id3v2.setLeadArtist(dto.getLeadArtist());
		id3v2.setSongComment(dto.getSongComment());
		id3v2.setSongGenre(dto.getSongGenre());
		id3v2.setSongLyric(dto.getSongLyric());
		id3v2.setSongTitle(dto.getSongTitle());
		id3v2.setTrackNumberOnAlbum(dto.getTrackNumberOnAlbum());
		id3v2.setYearReleased(dto.getYearReleased());
	}

}
